﻿using System;

namespace FreeSwitch.EventSocket
{
	/// <summary>
	/// Converts FS channel name into small
	/// </summary>
	public class ChannelName
	{
		private string _hostName;

		/// <summary>
		/// Empty instance
		/// </summary>
		public readonly static ChannelName Empty = new ReadOnlyChannelName();

		/// <summary>
		/// Initializes a new instance of the <see cref="ChannelName"/> class.
		/// </summary>
		public ChannelName()
		{
			_hostName = string.Empty;
		}

		/// <summary>
		/// ProfileName for the dial plan/sip.
		/// </summary>
		public virtual string ProfileName { get; set; }

		/// <summary>
		/// Extension / User name for the channel
		/// </summary>
		public virtual string Address { get; set; }

		/// <summary>
		/// Where the extension/user is calling from.
		/// </summary>
		public virtual string HostName
		{
			get { return _hostName; }
			set
			{
				if (value == null)
				{
					_hostName = string.Empty;
					return;
				}

				int pos = value.IndexOf(':');
				_hostName = pos == -1 ? value : value.Substring(0, pos);
			}
		}

		/// <summary>
		/// Gets or sets protocol used for communication.
		/// </summary>
		/// <remarks>
		/// <c>sofia</c> = sip
		/// </remarks>
		public virtual string Protocol { get; set; }


		/// <summary>
		/// Parse FS formatted channel name
		/// </summary>
		/// <param name="value">String to parse</param>
		public void Parse(string value)
		{
			string[] bits = value.Split('/');
			if (bits.Length != 3)
				return;

			Protocol = bits[0];
			ProfileName = bits[1];
			string[] userParts = bits[2].Split('@');
			if (userParts.Length == 2)
			{
				Address = userParts[0];
				HostName = userParts[1];
			}
			else
				Address = bits[2];
		}

		/// <summary>
		/// Returns FS formatted string
		/// </summary>
		/// <returns></returns>
		public override string ToString()
		{
			return Protocol + "/" + ProfileName + "/" + Address + "@" + _hostName;
		}
	}

	public class ReadOnlyChannelName : ChannelName
	{
		/// <summary>
		/// Extension / User name for the channel
		/// </summary>
		/// <value></value>
		public override string Address
		{
			get
			{
				return base.Address;
			}
			set
			{
				throw new InvalidOperationException("Channel name is read-only.");
			}
		}

		/// <summary>
		/// Where the extension/user is calling from.
		/// </summary>
		/// <value></value>
		public override string HostName
		{
			get
			{
				return base.HostName;
			}
			set
			{
				throw new InvalidOperationException("Channel name is read-only.");
			}
		}

		/// <summary>
		/// ProfileName for the dial plan/sip.
		/// </summary>
		/// <value></value>
		public override string ProfileName
		{
			get
			{
				return base.ProfileName;
			}
			set
			{
				throw new InvalidOperationException("Channel name is read-only.");
			}
		}

		/// <summary>
		/// Gets or sets protocol used for communication.
		/// </summary>
		/// <value></value>
		/// <remarks>
		/// 	<c>sofia</c> = sip
		/// </remarks>
		public override string Protocol
		{
			get
			{
				return base.Protocol;
			}
			set
			{
				throw new InvalidOperationException("Channel name is read-only.");
			}
		}
	}
}